﻿using ExcelDataReader;
using FPSO.HMI.Utils;
using FPSO.Models.Constant;
using FPSO.Models.Domain;
using FPSO.Models.ViewModel;
using FPSO.Services;
using FPSO.Services.Impl;
using FPSO.Services.Utils;
using Google.Protobuf.WellKnownTypes;
using Opc.Ua;
using OpcUaHelper;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using System.Xml;
using System.Xml.Linq;
using FPSO.Models;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using PrismMVVMLibrary.DesignTime;
using System.Security.Cryptography;
using System.Windows.Controls.Primitives;
using FPSO.Models.ViewModel.Controls;
using static FPSO.Models.Constant.TankConstant;
using MySqlX.XDevAPI.Relational;
using FPSO.Models.TagMapping;
using HelixToolkit.Wpf;
using System.Windows.Media.Media3D;

namespace FPSO.HMI.Views
{
    /// <summary>
    /// OPCMonitor.xaml 的交互逻辑
    /// </summary>
    public partial class StatusMonitorView : UserControl
    {
        private StatusMonitorViewModel viewModel;
		private SafeLoadAlgorithmService algorithmService;
		private Dictionary<string, double> FullDic;

		/// <summary>
		/// 随机数据生成计时器
		/// </summary>
		private DispatcherTimer taskTimer;

		private static ThresholdUtil.Threshold threshold = new ThresholdUtil.Threshold();

		public StatusMonitorView()
        {
            InitializeComponent();

            viewModel = new StatusMonitorViewModel();
			List<ConstantTankInfo> tankinfos = TankConstant.ConstantList;
			FullDic = new Dictionary<string, double>();
			foreach(ConstantTankInfo tankInfo in tankinfos)
			{
				FullDic.Add(tankInfo.TankAbName, 0);
			}

			algorithmService = SafeLoadAlgorithmService.GetInstance();

			this.DataContext = viewModel;

            threshold.BorderLeft = 0;
            threshold.Minn = 20;
            threshold.Min = 40;
            threshold.Max = 70;
            threshold.Maxx = 90;
            threshold.BorderRight = 100;

			ModelImporter import = new ModelImporter();

			string modelPath1 = "D:\\PROJECTS_CSharp\\FPSO_20230404\\CO1P.stl";
			var initGroup2 = import.Load(modelPath1);
			var m0 = (MeshGeometry3D)((GeometryModel3D)initGroup2.Children[0]).Geometry;
			var outsideMaterial = MaterialHelper.CreateMaterial(Colors.Red, 0.1);
			var insideMaterial = MaterialHelper.CreateMaterial(Colors.Blue);

			GeometryModel3D modelVisual3d2 = new GeometryModel3D
			{
				Geometry = m0,
				Material = outsideMaterial,
				BackMaterial = insideMaterial
			};

			Model3DGroup group = new Model3DGroup();
			group.Children.Add(modelVisual3d2);

			modelPath1 = "D:\\PROJECTS_CSharp\\FPSO_20230404\\CO1S.stl";
			var initGroup3 = import.Load(modelPath1);
			var m1 = (MeshGeometry3D)((GeometryModel3D)initGroup3.Children[0]).Geometry;
			var outsideMaterial1 = MaterialHelper.CreateMaterial(Colors.Green, 0.1);
			var insideMaterial1 = MaterialHelper.CreateMaterial(Colors.Transparent);
			GeometryModel3D modelVisual3d3 = new GeometryModel3D
			{
				Geometry = m1,
				Material = outsideMaterial1,
				BackMaterial = insideMaterial1
			};
			group.Children.Add(modelVisual3d3);
			ViewPortModel.Content = group;

			ShipCalcState shipCalcState = setTableInfo();
			setShipInfo(shipCalcState);

			taskTimer = new DispatcherTimer();
			taskTimer.Interval = TimeSpan.FromSeconds(2);
			taskTimer.Tick += TaskTimer_Tick;
			taskTimer.Start();
		}

		protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
        }

        private void TaskTimer_Tick(object sender, EventArgs e)
        {
			ShipCalcState shipCalcState = setTableInfo();
			setShipInfo(shipCalcState);
			setTanksFig();
		}

        /// <summary>
        /// 生成船舶状态随机数据
        /// </summary>
        private void setShipInfo(ShipCalcState shipCalcState)
        {
            // 风速
            viewModel.WindSpeed = CommUtil.GetDoubleNumber(0, 100, 2);
            // 风向
            viewModel.WindDirection = CommUtil.GetDoubleNumber(0, 100, 2);
            // 经度
            viewModel.Longitude = CommUtil.GetDoubleNumber(-180, 180, 3);
            // 纬度
            viewModel.Latitude = CommUtil.GetDoubleNumber(-30, 30, 3);
            // 左舵角
            viewModel.LeftRudderAngle = CommUtil.GetDoubleNumber(-30, 30, 3);
            // 右舵角
            viewModel.RightRudderAngle = CommUtil.GetDoubleNumber(-30, 30, 3);
            // 纵倾
            viewModel.TrimAngle = CommUtil.GetDoubleNumber(-5, 5, 3);
            // 横倾
            viewModel.HeelAngle = CommUtil.GetDoubleNumber(-5, 5, 3);
            // 吃水-左
            viewModel.DraftLeft = CommUtil.GetDoubleNumber(-5, 5, 2);
            // 吃水-右
            viewModel.DraftRight = CommUtil.GetDoubleNumber(-5, 5, 2);
            // 吃水-前
            viewModel.DraftFront = CommUtil.GetDoubleNumber(-5, 5, 2);
            // 吃水-后
            viewModel.DraftBack = CommUtil.GetDoubleNumber(-5, 5, 2);

			viewModel.DispValue = shipCalcState.Disp;
			viewModel.DeadWeightValue = shipCalcState.Disp;
			viewModel.LightShipValue = shipCalcState.Disp;
			viewModel.FreeWeightValue = shipCalcState.Disp;
			viewModel.CargoWeightValue = shipCalcState.Cargow;
			viewModel.CargoWeightValue = shipCalcState.Ballastw;
			viewModel.KMTValue = shipCalcState.KMT;
			viewModel.VcgValue = shipCalcState.VCG;
			viewModel.LcgValue = shipCalcState.LCG;
			viewModel.GMValue = shipCalcState.GM;

			viewModel.SFValue = shipCalcState.MaxPersf;
			viewModel.BMValue = shipCalcState.MaxPerbm;
			viewModel.SFMaxValue = shipCalcState.MaxPersf;
			viewModel.BMMaxValue = shipCalcState.MaxPerbm;
		}

        /// <summary>
        /// 生成舱室装载随机数据
        /// </summary>
        private void setTanksFig()
        {
			//按照FullDic的舱室顺序为界面赋值
			//暂定货油舱赋值规则1p,1s,2p,2s....5p,5s,slopp,slops
			//暂定压载舱赋值规则fpt,1p,1s,2p,2s....5p,5s,aptp,apts
			List<ConstantTankInfo> tankinfos = TankConstant.ConstantList;
			int i = 0;
			string tankabname = tankinfos[i].TankAbName;
			double fullvalue = FullDic[tankabname];
			i++;
   //         viewModel.H1P = fullvalue;
   //         h1p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H1S = fullvalue;
			//h1s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H2P = fullvalue;
   //         h2p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H2S = fullvalue;
			//h2s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H3P = fullvalue;
   //         h3p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H3S = fullvalue;
			//h3s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H4P = fullvalue;
   //         h4p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H4S = fullvalue;
			//h4s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H5P = fullvalue;
   //         h5p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.H5S = fullvalue;
			//h5s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y1P = fullvalue;
   //         y1p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y1S = fullvalue;
			//y1s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y2P = fullvalue;
   //         y2p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y2S = fullvalue;
			//y2s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y3P = fullvalue;
   //         y3p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y3S = fullvalue;
			//y3s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y4P = fullvalue;
   //         y4p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y4S = fullvalue;
			//y4s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y5P = fullvalue;
   //         y5p.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);

			//tankabname = tankinfos[i].TankAbName;
			//fullvalue = FullDic[tankabname];
			//i++;
			//viewModel.Y5S = fullvalue;
			//y5s.Background = ThresholdUtil.GetTankFillColor(fullvalue, threshold);
		}

		/// <summary>
		/// 生成单元格数据
		/// </summary>
		private ShipCalcState setTableInfo()
        {
			List<ConstantTankInfo> tankinfos = TankConstant.ConstantList;
			if (viewModel.TableData.Count > 0)
			{
				viewModel.TableData.Clear();
			}

			Dictionary<string, double> levelDic = new Dictionary<string, double>();
			foreach (ConstantTankInfo tankInfo in tankinfos)
			{
				string tankname = tankInfo.TankAbName;
				//NOTICE 临时测试程序
				double random_up = 10;
				if (tankname.IndexOf("WBT") > -1)
					random_up = 0.2;
				double level = CommUtil.GetDoubleNumber(0, random_up, 2);
				levelDic.Add(tankname, level);
			}
			ManualCalcResult calcResult = algorithmService.CallManualCalc(levelDic, 2);
			if (calcResult != null)
			{
				//显示数据分为直接显示接收数据和显示计算返回的数据两部分，后者必须要接入safeload后台
				ShipCalcState shipDraught = calcResult.ShipCalc;
				List<TankCalcState> tankCalcStates = calcResult.tankCalcStates;
				foreach(TankCalcState tankCalcState in tankCalcStates)
				{
					FullDic[tankCalcState.Abname] = tankCalcState.Full;
					viewModel.TableData.Add(new DataItem
					{
						Name = tankCalcState.Abname,
						Comm = "",
						EmptyHeight = tankCalcState.Inn,
						Volume = tankCalcState.Volume,
						Density = tankCalcState.Density,
						Weight = tankCalcState.Weight,
						Percentage = tankCalcState.Full,
						Temperature = 0,
						Pressure = 0,
						LiquidLevel = tankCalcState.Inn,
						CenterOfGravityX = tankCalcState.LCG,
						CenterOfGravityY = tankCalcState.TCG,
						CenterOfGravityZ = tankCalcState.VCG,
						LateralMomentOfInertia = tankCalcState.Rate,
						LateralInertiaType = "类型名称"
					});
				}
				return shipDraught;
			}
			return null;
        }

        /// <summary>
        /// 单元格编辑事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
        {
            DataGridCell cell = GetCell(e.Row, e.Column);

            if (cell != null)
            {
                TextBox textBox = e.EditingElement as TextBox;
                if (textBox != null)
                {
                    string editedText = textBox.Text;

                    if (!string.IsNullOrEmpty(editedText))
                    {
                        int editedValue;
                        if (int.TryParse(editedText, out editedValue))
                        {
                            // 根据条件更改背景色
                            if (editedValue > 50)
                            {
                                cell.Background = Brushes.Green; // 例如：值大于50为绿色
                            }
                            else
                            {
                                cell.Background = Brushes.Red; // 小于等于为红色
                            }
                        }
                    }
                }
            }
        }

        private DataGridCell GetCell(DataGridRow row, DataGridColumn column)
        {
            if (row != null && column != null)
            {
                DataGridCellsPresenter presenter = FindVisualChild<DataGridCellsPresenter>(row);

                if (presenter != null)
                {
                    int columnIndex = column.DisplayIndex;

                    if (columnIndex < presenter.Items.Count)
                    {
                        DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
                        return cell;
                    }
                }
            }
            return null;
        }

        private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);

                if (child != null && child is childItem)
                    return (childItem)child;

                childItem childOfChild = FindVisualChild<childItem>(child);

                if (childOfChild != null)
                    return childOfChild;
            }
            return null;
        }
    }
}
